#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 定义结构体类型--此时不占用内存
// 学生信息结构体
struct Student{
	int id;			// 学号
	char name[32];	// 姓名
	short score;	// 成绩
	char gender;	// 性别
};

int main(int argc, const char *argv[])
{
	// 使用结构体类型 定义了结构体变量 -- 占用内存
	struct Student s1;
	s1.id = 1001;
	strcpy(s1.name, "zhangsan"); // 注意 数组名不能用 = 赋值
	s1.score = 98;
	s1.gender = 'M';
	printf("s1.id = [%d] s1.name = [%s] s1.score = [%d] s1.gender = [%c]\n", \
			s1.id, s1.name, s1.score, s1.gender); // 1001 zhangsan 98 M

	struct Student s2;
	s2.id = 1002;
	printf("s2.id = [%d] s2.name = [%s] s2.score = [%d] s2.gender = [%c]\n", \
			s2.id, s2.name, s2.score, s2.gender); // 1002 随机值
	// 每个结构体变量都有自己的内存空间 都有自己的成员
	// 修改一个结构体变量的成员  不影响其他结构体变量
	printf("s1.id = [%d] s1.name = [%s] s1.score = [%d] s1.gender = [%c]\n", \
			s1.id, s1.name, s1.score, s1.gender); // 1001 zhangsan 98 M

	// 结构体变量间可以直接相互赋值
	struct Student s3;
	s3 = s1;
	printf("s3.id = [%d] s3.name = [%s] s3.score = [%d] s3.gender = [%c]\n", \
			s3.id, s3.name, s3.score, s3.gender); // 1001 zhangsan 98 M

	// 注意：使用指针的三个步骤
	// 1.定义指针变量
	// 2.明确指针的指向 (可以指向已经分配了空间的变量  也可以指向堆区分配的空间)
	// 3.操作指向的空间

	// 定义结构体指针
	struct Student *p1 = NULL;
	p1 = &s1; // 让 p1 指向 s1 
	// p1 指向 s1 之后 就可以访问s1对应的内存了
	p1->id = 1234;
	p1->score = 100;
	printf("p1->id = [%d] p1->name = [%s] p1->score = [%d] p1->gender = [%c]\n", \
			p1->id, p1->name, p1->score, p1->gender); // 1234 zhangsan 100 M
	
	// 指向堆区分配的空间
	struct Student *p2 = NULL;
	p2 = (struct Student *)malloc(sizeof(struct Student));
	if(NULL == p2){
		return -1;
	}
	p2->id = 1005;
	strcpy(p2->name, "xiaoming");
	p2->score = 60;
	p2->gender = 'W';
	printf("p2->id = [%d] p2->name = [%s] p2->score = [%d] p2->gender = [%c]\n", \
			p2->id, p2->name, p2->score, p2->gender); // 1005 xiaoming 60 W
	// 释放堆区的空间
	free(p2);
	p2 = NULL;
	
	return 0;
}
